This document provides information about the ODF shared library.
Table of Contents
-------------------------
• Shipping ODFLibrary
• Release-to-Release Binary Compatibility
• SOM vs. Extern "C" Interfaces
• Public vs Private APIs
• C++ Wrapper Classes
• Smart Pointers
• Publicly Exported Functions (by Subsystem)
All parts you build with ODF Release 2 require the ODF shared library ODFLibrary 1.1. ODFLibrary contains code from the Foundation and OS layers of ODF that is shared by all ODF parts. The design choice to package part of ODF as a shared library has ramifications that you should be aware of when you develop ODF parts. Those ramifications are covered here.
Shipping ODFLibrary
When you build ODF part editors with ODF Release 2, you must link against ODFLibrary 1.1. When you ship your part editors, you must provide an installer. Your installer should install the ODFLibrary along with your part editors into the 'Editors' folder. If an ODFLibrary is already present on your system, check the version number. Do not install an older version over a more recent one. The ODFLibrary will maintain release to release binary compatibility so that older part editors will still work with the most recent version of the library.
Release-to-Release Binary Compatibility
When you ship a part built with ODF Release 2, your part editor (for example, WhizzyPart 1.0) and ODFLibrary 1.1 are installed into the user's Editors folder. Meanwhile, we're busy developing ODF Release 3. ODF R3 may have an improved ODFLibrary, say version 1.2. Along the way, we may have discovered and fixed bugs in ODFLibrary and released updates on the net, say versions 1.1.1 and 1.1.2. Any of these versions could be installed into the Editors folder of your users of WhizzyPart 1.0. This means that we (the ODF team) must ensure backwards compatibility of ODFLibrary, or we'll break all ODF parts built against prior versions of ODFLibrary.
Fortunately, the Code Fragment Manager (CFM) and the CFM Runtime make this relatively easy. We are not allowed to modify any of the exported APIs, but we can add new APIs, fix bugs, and even completely replace implementations beneath the APIs, and still be backwards compatible.
Note that classes and APIs defined in the ODF static libraries (i.e. not part of ODFLibrary) can be modified in future releases of ODF. This means that when we ship ODF Release 3 (and later) that you may need to modify your source code and rebuild your part editor in order to take advantage of new features and improvements in the architecture.
SOM vs. Extern "C" Interfaces
The code in the ODF library is the implementation for much of the Foundation and OS layers of ODF. The classes in these subsystems were originally designed as C++ classes, but in order to move the code into a shared library it was necessary to rearchitect the code. Two choices were available to us: 1) convert the classes to SOM, and 2) convert to procedural APIs using C-style structs and functions (extern "C"). We ended up using both mechanisms. ODFLibrary 1.1 has 21 SOM classes and 491 extern "C" functions.
Public vs Private APIs
If you examine the list of exported functions from ODFLibrary you will see that most of them (395, to be exact) are named FW_PrivXXX. Functions in ODF which begin with the "Priv" prefix are considered private, or internal, to ODF. These functions are used internally by ODF and should never need to be called by your part editor. In general, Priv functions are low-level (private) interfaces which are used by the implementation of higher-level (public) interfaces. This is definitely the case for the Priv functions in ODF Library. For example, ODFLibrary exports 42 private functions that begin with the prefix "FW_PrivString_". These functions are all implementations for the methods of the public class FW_CString. FW_CString is a normal C++ class, and is statically linked into every ODF part. However, every method of FW_CString is implemented as a single call to one of the FW_PrivString functions in ODFLibrary, so only a small amount of code is statically linked into your part.
C++ Wrapper Classes
FW_CString is an example of a wrapper class. Wrapper classes are thin wrappers around some other implementation. ODF uses wrapper classes for much of the functionality implemented in ODFLibrary. These wrapper classes are part of the public interface of ODF and are fully documented. It is interesting to note that wrapper classes allowed us to minimize the impact of moving to a shared library architecture. In ODF R2 there are wrapper classes whose interfaces are nearly identical to the full-fledged C++ classes from ODF 1.0d11.
Wrapper classes are not just used for wrapping the procedural C functions in ODFLibrary. ODF provides some wrapper classes that wrap SOM classes from the ODF library as well. For example, FW_OFile is a SOM class defined in ODFLibrary. In previous (pre-)releases of ODF, files were implemented using the FW_CFile class. FW_CFile was designed to be used as a stack-based object. Creating a FW_CFile object opened the file, and destroying the FW_CFile object closed the file. By placing the object on the stack, it was possible to guarantee that the file would be closed when the object went out of scope, even if an exception was thrown. SOM classes, however, cannot be created on the stack. We did not want to give up the exception safety we get from creating FW_CFile objects on the stack, so we created a C++ class, FW_PFile, to wrap the FW_OFile class.
Smart Pointers
FW_PFile is a C++ class that wraps the SOM class FW_OFile. FW_PFile and FW_OFile together provide an interface and functionality almost identical to the old class FW_CFile. Developers who used pre-release versions of ODF and had references to FW_CFile objects can very likely just search for FW_CFile and replace it with FW_PFile and their code will work (assuming other similar renamings are performed, and some . operators are changed to -> operators). So why didn't we leave FW_CFile named as it was? FW_PFile uses the P prefix instead of the C prefix because it is a smart pointer. A smart pointer is an instance of class that overrides the member-selection operator (->) so that it can act as a pointer to some other representation object. FW_PFile is a class that has a data member which is a pointer to a FW_OFile representation object, and overrides the operator-> method to allow access to the FW_OFile object. Given an instance of FW_PFile, you can directly call any of the public member functions of FW_OFile. Note that by simply defining the operator-> method, the class effectively inherits all of the public protocol of the representation class. However, this protocol doesn't appear in the class declaration for the smart pointer. We use the P prefix so that you'll remember that you can use the protocol of the representation class.
Publicly Exported Functions (by Subsystem)
There are 21 SOM classes and 96 public procedures exported by the ODFLibrary. The following summarizes, by subsystem, the public APIs from ODFLibrary for each subsystem. Note that some subsystems have no public APIs exported by ODFLibrary. In all such cases, there will be public APIs defined by classes in one of the ODF static libraries that are linked into your part. See the ODF Class Reference or Engineering Notes for more information.
NOTE: We chose to use SOM to make the 21 SOM classes so that it would be possible to create subclasses. However, it is not required that you subclass any of the 21 SOM classes below, and most ODF part developers will have no need to do so. Furthermore, there exist public C++ wrappers for most of the SOM classes.
Foundation::FWCommon
This subsystem defines the following public functions:
FW_PrimitiveSetMemory
FW_PrimitiveCopyMemory
FW_PrimitiveFreeBlock
FW_PrimitiveGetBlockSize
FW_PrimitiveResizeBlock
FW_PrimitiveAllocateBlock
FW_PrimitiveCharacterIsSpace
FW_PrimitiveCharacterToLower
FW_PrimitiveCharacterToUpper
FW_PrimitiveStringFindCharacter
FW_PrimitiveStringCatenate
FW_PrimitiveStringCopy
FW_PrimitiveStringDuplicate
FW_PrimitiveStringCompare
FW_PrimitiveStringEqual
FW_PrimitiveStringLength
Foundation::FWCollect
All exported functions are private.
Foundation::FWDebug
All exported functions are private.
Foundation::FWRunTyp
No functions are exported from the shared library.
Foundation::FWExcLib
No functions are exported from the shared library.
Foundation::FWMemory
All exported functions are private.
Foundation::FWStream
All exported functions are private.
This subsystem defines six SOM classes:
FW_OSink
FW_OBufferedSink
FW_OMemorySink
FW_OObjectRegistry
FW_OBasicObjectRegistry
FW_ORandomAccessSink
Foundation::FWString
This subsystem defines the following public functions:
FW_LocaleIsSingleByte
FW_CharIsDoubleByte
This subsystem defines five SOM classes:
FW_OTextRunReader
FW_OTextRunWriter
FW_OMemoryRunReader
FW_OMemoryRunWriter
FW_OStringRunWriter
Foundation::FWRefCnt
This subsystem defines one SOM class:
FW_ORefCount
OS::FWFiles
This subsystem defines four SOM classes:
FW_OFile
FW_OFileSink
FW_OFileSpecification
FW_ODirectorySpecification
OS::FWOSMisc
This subsystem defines the following public functions:
FW_GetODFLibraryVersion
OS::FWODMisc
All exported functions are private.
This subsystem defines one SOM class:
FW_OStorageUnitSink
OS::FWResour
This subsystem defines four SOM classes:
FW_OResourceFile
FW_OResource
FW_OResourceSink
OS::FWThread
This subsystem defines the following public functions:
FW_Thread_NoteCreation
FW_Thread_NoteTermination
FW_Thread_NoteSwitch
OS::FWToolbx
This subsystem defines the following public functions:
FW_MacGetMaxIntersectedDevice
FW_MacZoomWindow
FW_CenterRectOnScreen
FW_GetMainScreenBounds
FW_Beep
FW_GetTickCount
FW_PositionModalDialog
FW_FitWindowToScreen
FW_SetWindowSize
FW_SetWindowPosition
FW_GetWindowSize
FW_GetWindowPosition
FW_SetWindowTitle
FW_GetWindowTitle
FW_GetWindowBorderSize
FW_ScreenToWindow
FW_WindowToScreen
OS::FWGraphics
This subsystem defines the following public functions: